package cn.sc.summer.mybatis.service;

import cn.hutool.core.text.CharSequenceUtil;
import cn.sc.summer.mybatis.model.DataSourceX;
import cn.sc.summer.mybatis.table.TableService;
import cn.sc.summer.mybatis.table.datasource.DataSourceTableInfo;
import cn.sc.summer.constant.mybatisplus.datasource.TableInfo;
import cn.sc.summer.constant.mybatisplus.datasource.TableInfoParam;
import cn.sc.summer.mybatis.constant.TableResource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类名：数据源接口
 *
 * @author a-xin
 * @date 2024/8/27 09:43
 */
@Slf4j
@Service
public class TableServiceImpl implements TableService {

    private static final long serialVersionUID = -1400677305703071516L;

    /**
     * 获取指定数据库表信息
     *
     * @param jdbcTemplate jdbc连接
     * @return 数据库表信息
     */
    @Override
    public List<TableInfoParam> getTables(JdbcTemplate jdbcTemplate) {
        String dataSourceType = checkDataSourceType(Objects.requireNonNull(jdbcTemplate.getDataSource()));
        DataSourceTableInfo tableInfoService = TableResource.TABLE_CONFIG_INFO.get(dataSourceType);
        return tableInfoService.getTableInfo(jdbcTemplate);
    }

    /**
     * 获取指定数据库表信息
     *
     * @param dataSource 数据源信息
     * @return 数据库表信息
     */
    @Override
    public List<TableInfoParam> getTables(DataSourceX dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return getTables(jdbcTemplate);
    }

    /**
     * 获取数据库表字段信息
     *
     * @param jdbcTemplate jdbc连接
     * @return 对应表字段信息
     */
    @Override
    public List<TableInfo> getTableDetail(JdbcTemplate jdbcTemplate) {
        String dataSourceType = checkDataSourceType(Objects.requireNonNull(jdbcTemplate.getDataSource()));
        DataSourceTableInfo tableInfoService = TableResource.TABLE_CONFIG_INFO.get(dataSourceType);
        return tableInfoService.getColumnInfo(jdbcTemplate);
    }

    /**
     * 获取数据库表字段信息
     *
     * @param dataSource 数据源信息
     * @return 对应表字段信息
     */
    @Override
    public List<TableInfo> getTableDetail(DataSourceX dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        return getTableDetail(jdbcTemplate);
    }

    /**
     * 校验数据源类型是否合法
     *
     * @param dataSource 数据源产品名称
     * @return 数据源类型
     */
    public String checkDataSourceType(DataSource dataSource) {
        List<String> dataSourceTypeName = TableResource.ALL_DATASOURCE_INFO.stream().map(DataSourceX::getDataSourceTypeName)
                .collect(Collectors.toList());
        try {
            Connection connection = dataSource.getConnection();
            String databaseProductName = connection.getMetaData().getDatabaseProductName().toLowerCase();
            if (CharSequenceUtil.isBlank(databaseProductName) || !dataSourceTypeName.contains(databaseProductName)) {
                throw new RuntimeException("Unsupported data source types: " + databaseProductName);
            }
            return databaseProductName;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}
